package com.skywolf.chem.usercenterapi;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.skywolf.chem.common.enums.ResponseCodeEnum;
import com.skywolf.chem.common.sysconfig.response.RespData;
import com.skywolf.chem.usercenterapi.entity.CustomerInfo;
import com.skywolf.chem.usercenterapi.pojo.UserParam;
import com.skywolf.chem.usercenterapi.pojo.WechatBindPhoneParam;
import com.skywolf.chem.usercenterapi.service.ICustomerInfoService;
import com.skywolf.chem.usercenterapi.pojo.LoginParam;
import com.skywolf.chem.utils.CryptUtil;
import com.skywolf.chem.utils.PhoneUtils;
import com.skywolf.chem.utils.RequestConstans;
import com.skywolf.chem.utils.sms.SendSms;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

/**
 * <p>
 * app端用户表 前端控制器
 * </p>
 *
 * @author 
 * @since 2020-06-09
 */
@Slf4j
@RestController
@Api(value = "用户相关-用户端", description = "用户相关-用户端")
@RequestMapping("/ct/user/customer-info")
public class CustomerInfoController {

    @Autowired
    private ICustomerInfoService customerInfoService;


    @ApiOperation(value = "获取用户信息",notes = "获取用户信息")
    @RequestMapping(value = "/getUserInfo",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updatePassword(HttpServletRequest request) {
        String uid = request.getHeader("user_id");
        CustomerInfo info = customerInfoService.getById(Long.valueOf(uid));
        info.setUserPwd(null);
        return RespData.success(info);
    }

    @ApiOperation(value = "更改密码-通过原密码更改",notes = "更改密码-通过原密码更改")
    @RequestMapping(value = "/updatePassword",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updatePassword(HttpServletRequest request,@RequestBody LoginParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo info = customerInfoService.getById(Long.valueOf(uid));
        if(StringUtils.isNotBlank(info.getUserPwd())){
            if(StringUtils.isBlank(param.getStartPassword())){
                return RespData.failure(ResponseCodeEnum.USER_INVALID_OLD_PASSWORD);
            }
            //用户传递的初始密码
            String initPwd = CryptUtil.EncoderByMd5(param.getStartPassword());
            if(!initPwd.equals(info.getUserPwd())){
                return RespData.failure(ResponseCodeEnum.USER_INVALID_OLD_PASSWORD);
            }
        }
        CustomerInfo cus = new CustomerInfo();
        cus.setId(param.getUid());
        cus.setUserPwd(CryptUtil.EncoderByMd5(param.getPassword()));
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }


    @ApiOperation(value = "更改密码-发短信",notes = "更改密码--发短信")
    @RequestMapping(value = "/updatePwdByMsg",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updatePwdByMsg(HttpServletRequest request) {
        String uid = request.getHeader("user_id");
        CustomerInfo user = customerInfoService.getById(Long.valueOf(uid));
        if(StringUtils.isBlank(user.getBindPhone())){
            return RespData.error("请先绑定手机号");
        }
        String code = PhoneUtils.getCode();
        SendSms.sendMsg(user.getBindPhone(), code);

        CustomerInfo cus = new CustomerInfo();
        cus.setCodeTime(LocalDateTime.now());
        cus.setMscCode(code);
        cus.setId(user.getId());
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }

    @ApiOperation(value = "更改密码-验证短信",notes = "更改密码-通过原密码更改")
    @RequestMapping(value = "/updatePwdByMsgCheck",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updatePwdByMsgCheck(HttpServletRequest request,@RequestBody LoginParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo cus = customerInfoService.getById(Long.valueOf(uid));
        Long nowTime = System.currentTimeMillis()/1000;
        Long codeTime = cus.getCodeTime().toEpochSecond(ZoneOffset.of("+8"));
        if(nowTime-codeTime>300){
            return RespData.failure(ResponseCodeEnum.CODE_EXPIRE);
        }
        if(!param.getMacCode().equals(cus.getMscCode())){
            return RespData.failure(ResponseCodeEnum.CODE_ERROR);
        }
        cus.setUserPwd(CryptUtil.EncoderByMd5(param.getPassword()));
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }


    @ApiOperation(value = "更改原手机-发短信",notes = "更改原手机-发短信")
    @RequestMapping(value = "/updatePhoneByMsg",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updatePhoneByMsg(HttpServletRequest request,@RequestBody UserParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo user = customerInfoService.getById(Long.valueOf(uid));
//        if(!user.getBindPhone().equals(param.getPhone())){
//            return RespData.failure(ResponseCodeEnum.OLD_PHONE_ERROR);
//        }
        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomerInfo::getBindPhone,param.getPhone()).eq(CustomerInfo::getPhoneStatus,1);
        CustomerInfo cusOld = customerInfoService.getOne(queryWrapper);
        if(cusOld!=null){
            return RespData.error("该手机号已经被绑定");
        }
        String code = PhoneUtils.getCode();
        SendSms.sendMsg(user.getBindPhone(), code);

        CustomerInfo cus = new CustomerInfo();
        cus.setCodeTime(LocalDateTime.now());
        cus.setMscCode(code);
        cus.setId(user.getId());
        cus.setHistoryPhone(param.getPhone());
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }

    @ApiOperation(value = "更改原手机-验证短信",notes = "更改原手机-验证短信")
    @RequestMapping(value = "/updatePhoneByMsgCheck",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updatePhoneByMsgCheck(HttpServletRequest request,@RequestBody UserParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo cus = customerInfoService.getById(Long.valueOf(uid));
        Long nowTime = System.currentTimeMillis()/1000;
        Long codeTime = cus.getCodeTime().toEpochSecond(ZoneOffset.of("+8"));
        if(nowTime-codeTime>300){
            return RespData.failure(ResponseCodeEnum.CODE_EXPIRE);
        }
        if(!param.getMsgCode().equals(cus.getMscCode())){
            return RespData.failure(ResponseCodeEnum.CODE_ERROR);
        }
        String oldPhone = cus.getBindPhone();
        cus.setBindPhone(cus.getHistoryPhone());
        cus.setHistoryPhone(oldPhone);
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }


    @ApiOperation(value = "添加新手机-发短信",notes = "添加新手机-发短信")
    @RequestMapping(value = "/addPhoneByMsg",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> addPhoneByMsg(HttpServletRequest request,@RequestBody UserParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo user = customerInfoService.getById(Long.valueOf(uid));
        if(!user.getBindPhone().equals(user.getHistoryPhone())){
            return RespData.failure(ResponseCodeEnum.OLD_PHONE_CHECK_ERROR);
        }
        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomerInfo::getBindPhone,param.getPhone()).eq(CustomerInfo::getPhoneStatus,1);
        CustomerInfo cusOld = customerInfoService.getOne(queryWrapper);
        if(cusOld!=null){
            return RespData.failure(ResponseCodeEnum.PHONE_DUPLICATE);
        }

        String code = PhoneUtils.getCode();
        SendSms.sendMsg(param.getPhone(), code);

        CustomerInfo cus = new CustomerInfo();
        cus.setCodeTime(LocalDateTime.now());
        cus.setMscCode(code);
        cus.setId(user.getId());
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }

    @ApiOperation(value = "添加新手机-验证短信",notes = "添加新手机-验证短信")
    @RequestMapping(value = "/addPhoneByMsgCheck",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> addPhoneByMsgCheck(HttpServletRequest request,@RequestBody UserParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo cus = customerInfoService.getById(Long.valueOf(uid));

        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomerInfo::getBindPhone,param.getPhone()).eq(CustomerInfo::getPhoneStatus,1);
        CustomerInfo cusOld = customerInfoService.getOne(queryWrapper);
        if(cusOld!=null){
            return RespData.failure(ResponseCodeEnum.PHONE_DUPLICATE);
        }

        Long nowTime = System.currentTimeMillis()/1000;
        Long codeTime = cus.getCodeTime().toEpochSecond(ZoneOffset.of("+8"));
        if(nowTime-codeTime>300){
            return RespData.failure(ResponseCodeEnum.CODE_EXPIRE);
        }
        if(!param.getMsgCode().equals(cus.getMscCode())){
            return RespData.failure(ResponseCodeEnum.CODE_ERROR);
        }
        cus.setUserName(param.getPhone());
        cus.setBindPhone(param.getPhone());
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }


    @ApiOperation(value = "更新用户信息",notes = "更新用户信息")
    @RequestMapping(value = "/updateUserInfo",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> updateUserInfo(HttpServletRequest request,@RequestBody CustomerInfo param) {
        param.setUserPwd(null);
        String uid = request.getHeader("user_id");
        param.setId(Long.valueOf(uid));
        customerInfoService.updateById(param);
        return RespData.success("success");
    }


    @ApiOperation(value = "绑定手机号,发送短信",notes = "绑定手机号,发送短信")
    @RequestMapping(value = "/bindPhoneMessage",method = {RequestMethod.GET,RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> bindPhoneMessage(HttpServletRequest request,@RequestParam(value = "",required = true) String phone) {
        String uid = request.getHeader("user_id");
        if(!PhoneUtils.phoneCheck(phone)){
            return RespData.failure(ResponseCodeEnum.PHONE_ERROR);
        }
        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomerInfo::getBindPhone, phone);
        CustomerInfo cus = customerInfoService.getOne(queryWrapper);
        if(cus !=null && cus.getPhoneStatus().equals(1)){
            return RespData.failure(ResponseCodeEnum.PHONE_BIND);
        }
        String code = PhoneUtils.getCode();
        SendSms.sendMsg(phone, code);
        CustomerInfo info = new CustomerInfo();
        info.setCodeTime(LocalDateTime.now());
        info.setMscCode(code);
        info.setUserName(phone);
        info.setBindPhone(phone);
        info.setId(Long.valueOf(uid));
        customerInfoService.updateById(info);
        return RespData.success();
    }

    @ApiOperation(value = "绑定手机号,且验证短信",notes = "绑定手机号,且验证短信")
    @RequestMapping(value = "/bindPhone",method = {RequestMethod.GET,RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> bindPhone(HttpServletRequest request,@RequestParam(value = "",required = true) String phone,
                                             @RequestParam(value = "",required = true) String code) {
        String uid = request.getHeader("user_id");
        if(!PhoneUtils.phoneCheck(phone)){
            return RespData.failure(ResponseCodeEnum.PHONE_ERROR);
        }
        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomerInfo::getBindPhone, phone);
        CustomerInfo cus = customerInfoService.getOne(queryWrapper);
        if(cus !=null && cus.getPhoneStatus().equals(1)){
            return RespData.failure(ResponseCodeEnum.PHONE_BIND);
        }

        CustomerInfo info = customerInfoService.getById(Long.valueOf(uid));
        info.setCreatedTime(null);
        Long nowTime = System.currentTimeMillis()/1000;
        Long codeTime = info.getCodeTime().toEpochSecond(ZoneOffset.of("+8"));
        if(nowTime-codeTime>300){
            return RespData.failure(ResponseCodeEnum.CODE_EXPIRE);
        }
        if(!code.equals(info.getMscCode())){
            return RespData.failure(ResponseCodeEnum.CODE_ERROR);
        }
        info.setPhoneStatus(1);
        customerInfoService.updateById(info);
        return RespData.success();
    }



    @ApiOperation(value = "微信登录-绑定手机-发短信",notes = "微信登录-绑定手机-发短信")
    @RequestMapping(value = "/bindPhoneMsg",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<String> sendWechatLogBindPhone(HttpServletRequest request,@RequestBody WechatBindPhoneParam param) {
        String uid = request.getHeader("user_id");
        String code = PhoneUtils.getCode();
        SendSms.sendMsg(param.getPhone(), code);

        CustomerInfo cus = new CustomerInfo();
        cus.setCodeTime(LocalDateTime.now());
        cus.setMscCode(code);
        cus.setId(Long.valueOf(uid));
        cus.setUserName(param.getPhone());
        customerInfoService.updateById(cus);
        return RespData.success("success");
    }

    @ApiOperation(value = "微信登录-绑定手机-验证短信",notes = "微信登录-绑定手机-验证短信")
    @RequestMapping(value = "/wechatBindPhone",method = {RequestMethod.POST},produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public RespData<JSONObject> wechatBindPhone(HttpServletRequest request,@RequestBody WechatBindPhoneParam param) {
        String uid = request.getHeader("user_id");
        CustomerInfo cus = customerInfoService.getById(Long.valueOf(uid));
        Long nowTime = System.currentTimeMillis()/1000;
        Long codeTime = cus.getCodeTime().toEpochSecond(ZoneOffset.of("+8"));
        if(nowTime-codeTime>300){
            return RespData.failure(ResponseCodeEnum.CODE_EXPIRE);
        }
        if(!param.getMsgCode().equals(cus.getMscCode())){
            return RespData.failure(ResponseCodeEnum.CODE_ERROR);
        }

        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CustomerInfo::getBindPhone, cus.getUserName());
        CustomerInfo phoneUser = customerInfoService.getOne(queryWrapper);
        if(phoneUser!=null){
            //微信登录绑定手机，如果该手机下存在账号，就直接绑定该账号
            return RespData.failure(ResponseCodeEnum.PHONE_BIND);
        }
        //逻辑删除原账号
        cus.setDeleted(true);
        customerInfoService.updateById(cus);

        //绑定到有手机号的账号
        phoneUser.setWechatOpenid(cus.getWechatOpenid());
        phoneUser.setPhoneStatus(1);
        customerInfoService.updateById(phoneUser);

        String token = phoneUser.getId()+"|"+phoneUser.getUserName()+"|"+phoneUser.getUserPwd()+"|"+System.currentTimeMillis()/1000;
        String userToken = CryptUtil.IMDes3Encode(token, RequestConstans.decode_pwd);
        JSONObject obj = new JSONObject();
        obj.put("userToken",userToken);
        obj.put("userId",phoneUser.getId());
        return RespData.success(obj);
    }

}
